The WiiBot Project

Created by Ryan Connaughton, Notre Dame extended Research Community (NDeRC); and Matt Modlin, Riley High School, South Bend Community School Corporation.

See also the NDeRC Robotics System (NRS) curriculum page.)


Overview
This project aimed at combining the Vex robotics kit with Bluetooth communication in order to provide access to input from a Nintendo Wii remote ("Wiimote"). The resulting robot is a Vex robotic tank which is steered by turning the Wiimote like a steering wheel, with the "1" and "2" buttons being used for moving forward and backward, respectively. Generally speaking, the communication works as follows: A nearby PC, equipped with Bluetooth, acts as a server for the robot. The robot, also connected to a Bluetooth device, is able to exchange data with the PC using the wireless communication offered by Bluetooth. Additionally, the server PC is able to communicate with the Wiimote via Bluetooth- which is natively installed on the Wiimote (in fact, Bluetooth is used by the Wiimote to communicate with the Nintendo Wii, as well). Thus, with the proper setup, the Wiimote can be used to send data to the server PC, which can then interpret the input and relay commands to the Vex robot. The figure below shows the communication setup for the system.

sysdiagram2.jpg

Background
  • Vex Robotics Design System. The Vex Robotics Design System is a modular robotics kit intended for education. Included in the standard Vex kit are metal pieces for building robot framework, wheels, motors, bump sensors, the Vex microcontroller, and many other pieces. The microcontroller, essentially a low-power computer for controlling the robot, can be programmed using several methods in order to customize robot behavior. Programs for the Vex are written on a PC in the C programming language, compiled, and transferred to the microcontroller. Programs can be made in a drag-and-drop style using Vex's EasyC software (and its variants), or using MPLab's Programming kit (more advanced, but cheaper). For more information, see the Vex homepage.
  • Bluetooth. As a brief overview, Bluetooth is a wireless protocol for short-range, low-power communication. Bluetooth devices in the same area can be connected to one another to wirelessly transfer data. Typical applications of Bluetooth technology include mobile phones (i.e. bluetooth headsets), printers, digital cameras, etc. Expected range for Bluetooth devices is anywhere between 30ft to 300ft, depending on the particular Bluetooth device (and its power-consumption). See the Bluetooth wiki for more information on Bluetooth communication.
  • Wiimote. The Wiimote is the remote control for the Nintendo Wii game console. Beyond the typical button/joystick input mechanisms, there are three distinguishing features of the Wiimote that make it an interesting tool for experimentation. First, the Wiimote is also Bluetooth-enabled. As such, the state of all of its buttons, etc, can be transmitted to other nearby Bluetooth devices. Second, the Wiimote has accelerometers to describe the current orientation of the Wiimote. Finally, the front of the Wiimote has an infrared (IR) light detector. Typically used to track the IR sensor bar on the Nintendo Wii, the Wiimote can track up to four IR lights at a time. Both the state of the accelerometers and the coordinates of any detected IR light sources can be reported via Bluetooth like any other controller input. See the Wiimote wiki or Nintendo's website for more details.

Materials

Steps
  • Install MPLab or EasyC Pro, Visual C# Express, and the bluetooth drivers. For the remainder of this page, unless otherwise specified it is assumed that MPLab is being used. Using MPLab, update the master code on the Vex Controller (see Vex/MPLab documentation) and using the Vex kit, construct a vehicle. See here for details on setting up MPLab for this project.
  • Now, to connect the BlueSMiRF modem... On one side of the modem, the pins are labeled (see image below, courtesy of SparkFun's website). In particular, we are concerned with the inner four pins: VCC (power), GND (ground), TX-0 (transmit), and RX-I (receive).

bluesmirf_pins2.jpg

  • And below is a diagram of the Vex Controller pins:

VexPins2.jpg

  • The following describes how we will want to connect the BlueSMiRF to the Vex Controller:
BlueSMiRF Pin
Vex Controller Pin
VCC
VCC
GND
GND
RX-I
TX Data
TX-0
RX Data

  • So, you will want to connect the RX-I on the BlueSMiRF to the TX Data on the Vex Controller, and the TX-0 on the BlueSMiRF to the RX Data on the Vex Controller. Also, you will connect the GND on the BlueSMiRF to any of the GND pins on the Vex, and the VCC on the BlueSMiRF to any VCC on the Vex. For our connections, I used an ethernet cable, which contains 6 twisted strands of wire (though you only need 4 of them). Also, the ends of the wire were fixed to pin headers and soldered to the BlueSMiRF to guarantee stable connections. Below is an example image of our personal set up (we used a special cable instead of an ethernet cable in our final version).

vexsetup.jpg

  • With the Bluetooth modem connected to the Vex, the next step is to program the Vex Controller to read and write to the modem, and to use messages it receives. The MPLab software (and EasyC Pro, unlike the standard EasyC software) provides functionality to read and write data from the TX/RX ports on the top of the Vex controller. To use these functions in MPLab, use the "ReadSerialPortTwo()" function to read a byte from the modem (this function returns an 'unsigned char'), and the "WriteSerialPortTwo( unsigned char )" function to send a byte to the modem. (To use these functions in EasyC Pro, add "User Code" to your Vex program, and use the "ReadSerialPortTwo()" function). We skip the details of making the entire program, but essentially, our version starts with an initialization phase which allows the user to specify what motors and sensors are connected, followed by an infinite loop which:
    • Reads a 1-byte message from the modem (the message will be = 0 if no message is received)
    • Interprets message based on the value of the byte:
      • Motor Command - Tells the Vex Controller to set the specified motor to a specific value.
      • Port Query - Asks the Vex Controller to send back the value of the sensor on the specified input port.
    • Performs the appropriate response to the incoming message.
  • The above-mentioned program should be sufficiently generic to be used in most applications-- not just the WiiBot! If the Vex controller runs this program, then any command sent to the controller via Bluetooth can be interpreted and handled as a general-purpose command interface.
  • Because bytes can have a value ranging from 0-255, and some bits in each message are used to specify motor/port values, some precision is sacrificed for Motor Commands (ie, our motor values can now range from 0-29, and these values are adjusted to cover the full 0-255 range which is normally possible). One possible fix for this would be to send 2 bytes consecutively, one to specify a motor, and one to specify the value-- but for simplicity, we force each message to be exactly one byte in size.
  • Now that the Bluetooth is connected and interfaced with the Vex robot, we need a program on a computer capable of sending information to the Vex's Bluetooth modem. We elected to program in C# for numerous reasons:
    • Easy programming style for students/new programmers
    • Existing support for Wiimote interface
    • Easier potential integration with Microsoft Robotics Studio in the future
  • Begin by connecting the Bluetooth adapter to your PC, and establish communication with the BlueSMiRF device. With the Kensington adapter, this amounts to activating the device (right-click on the Bluetooth icon in the System Tray, and choose 'Start Bluetooth Device"). Then, again right-click the icon, and use the menu to "connect to a device". Make sure that your Vex controller is powered on. If it is receiving power, the BlueSMiRF should have a blinking red light. If this is the case, then the device should be detected by your Bluetooth adapter when it performs the device search (on my computer, the BlueSMiRF showed up as "FireFly"). Choose to connect to it. When prompter for a Pairing Key, enter the default device key for the BlueSMiRF modem: 1234. Finally, a list of available services should be displayed to you, with only one option, along with a configure button. Click the configure button to see what "COM port" is being used for the device, and then close it out, select the available service, and choose "Finish". This COM port is important, because it is the name of the port we will use to communicate with the BlueSMiRF device.
  • At this point, you have two options::
    • Users with no experience programming, who simply want to get communication working, may elect to use our C# Bluetooth communication functions. To do so, it is necessary to run our Vex Controller program on the Vex Controller as well. The communication functions we have created are wrapped up in a C# library. To use it, save the VexLib.dll file to any directory. Then, to include the functions in your project, do the following:
      • In the Solution Explorer window, right-click the "References" entry, and choose "Add Reference":

      csharp_include1.JPG
      • In the resulting window, choose the Browse tab, navigate to the VexLib.dll file, select it, and choose "Ok". At the top of your program's code, after the other "using ..." entries, add the line:
      • using VexLib;
      • That's it! You should be ready to use our code to communicate with the Vex. To do so, in your program, declare a VexConnection object, and connect to the appropriate COM port for the BlueSMiRF:
      • VexConnection vc = new VexConnection();
        vc.InitVex("COM5");
      • One last step is required to initialize the Vex Controller: You must tell the controller what each of its ports is connected to. In our program, by default, the controller assumes that there are no sensors or motors connected. To add sensors and motors, you will use the following functions:
      • vc.addMotor(1);        /* add motor to motor port 1 */
        vc.addServo(2);        /* add servo to motor port 2 */
        vc.addBumpSensor(1);   /* add bump sensor to port 1 */
        vc.addUSSensor(11,2);  /* add ultrasound to port 11, interrupt 1 */
        vc.finalizePorts();    /* tell the controller that there are no new sensors or motors to add */
      • Then, you may send Motor Commands and receive sensor values with ease. For example:
      • vc.SendMotorCommand(1,21);            /* set motor 1 to value 21 */
        int result = vc.GetPortValue(3);      /* get the value of sensor on port 3 */
      • A few notes:
        • Motor Commands should only be sent values ranging from 0 to 28. A value of 0 is full counter-clockwise, a value of 28 is full-clockwise, a value of 14 is halted, and all other values are interpolated between these (with rounding to nearest integers
        • While functions are provided to add motors and sensors to the controller without reprogramming it, one small change is required to the controller's program depending on your configuration: you must specify which ports are digital or analog input/output.
    • Users with some experience programming may elect to handle their own Bluetooth communication. To do this, in your code you should declare a new SerialPort object.... ie:
      • SerialPort vex_port = new SerialPort(comname, 115200, Parity.None, 8, StopBits.One);  
      • Where comname should be a string specifying the COM port of your BlueSMiRF connection (ie, "COM5"). Then, code such as:
      • vexPort.Write(new byte[] { message }, 0, 1);
      • can be used to send message, which would be of type byte, and receiving a message can be accomplished with:
      • int response = vexPort.ReadByte();
      • which technically returns a byte as well. If you plan to take this route, you may design whatever communication scheme you would like for your robot, so long as your Vex Controller program knows how to interpret the messages you send.
  • Finally, the last step is to use communication with the Wiimote. Using some fantastic work done by Brian Peek, integrating communication with the Wiimote is almost as simple as communication with the Vex Controller. In your C# project, again right-click on the "References" entry in the Solution Explorer window, and choose "Add Reference". In the "Browse" tab of the resulting window, navigate to and select the WiimoteLib.dll file, from the WiimoteLib.zip download.
  • At the top of your code, add the line:
  • using WiimoteLib;
  • Then in the body of your code, you can declare a Wiimote object, and connect to it. The following code does just that. Additionally, it specifies that the wiimote should report the Infrared and Accelerometer data in addition to the button data.
  • Wiimote wiimote1 = new Wiimote();
    wiimote1.Connect();
    wiimote1.SetReportType(InputReport.IRAccel, true);  
  • From then on, the WiimoteState object will contain the latest update from the Wiimote:
  • bool button_A = wiimote1.WiimoteState.ButtonState.A;    /* A button's value */
    float xAccel = wiimote1.WiimoteState.AccelState.Values.X ;  /* X-axis accelerometer value */
  • These values, along with the other Wiimote data can be used to interpret user commands, and send new commands to the Vex. See here for more documentation on the Wiimote library.
  • To connect the Wiimote to your computer's bluetooth adapter, a similar process is used as was required to connect the BlueSMiRF to the PC, with a few modifications:
    • Begin the PC's search for nearby bluetooth devices. Once the search has started, hold down the 1 and 2 buttons on the Wiimote, and DO NOT LET GO OF THEM until you have clicked "finished" in the LAST step of this process. Once pressed, the Wiimote LED's should begin flashing. If at any point they stop flashing, then the connection has failed between your PC and the Wiimote (unless you explicitly turned off the LED's in your program). The Wiimote should show up as "Nintendo RVL-CNT-01" in the list of detected devices-- choose it, and hit "Next".
    • When prompted for a Pairing Key, hit "Skip" or "Next" -- the Wiimote does not require a pairing key.
    • Choose the services for the Wiimote, once they appear, and select "Finish". Now, it is OK to release the 1 and 2 buttons on the Wiimote. The Wiimote LED's should continue flashing. even after communication is established.
  • That should be it! Add in whatever code you would like to read in Wiimote input and control the Vex. Soon, we will post the exact Vex and C# code we used to run the WiiBot. Below is a video of our WiiBot in action... Goodluck!










References:
[1] Brian Peek. Managed Library for Nintendo's Wiimote. http://blogs.msdn.com/coding4fun/archive/2007/03/14/1879033.aspx, http://www.codeplex.com/WiimoteLib, and http://www.brianpeek.com/forums/24.aspx
[2] List of Bluetooth Devices Compatible with Wiimote
[3] Vex Forum
[4] SparkFun's BlueSMiRF Webpage
[5] Ed Harfmann. MSRS Service for Vex Robotics. http://www.codeplex.com/VexMsrs/Thread/View.aspx?ThreadId=19851
[6] Vex Homepage



Acknowledgments:
Special thanks to Peter Bui, Brian Peek, and Vex Tech Support for help.



[1] Other Bluetooth devices may work, however, it has been noted that not all devices are compatible with the Wiimote. For details, see here. Drivers may vary based on which device you use.
[2] Other Bluetooth devices may work, however, I HIGHLY recommend this unit. If not, be aware that the Vex Controller uses a TTL interface for its ports, and that connecting a non-TTL device directly to the microcontroller may cause damage.